<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="WaWBi" id="WaWBi"><span data-lake-id="u342374e5" id="u342374e5">典型回答</span></h1>
  <p data-lake-id="ud6f31047" id="ud6f31047"><br></p>
  <p data-lake-id="u7bf48757" id="u7bf48757"><strong><span data-lake-id="uc1a952d6" id="uc1a952d6">Spring中Bean的创建过程其实可以分成两步，第一步叫做实例化，第二步叫做初始化。</span></strong></p>
  <p data-lake-id="u98111bb1" id="u98111bb1"><span data-lake-id="u43121501" id="u43121501">​</span><br></p>
  <p data-lake-id="ud770ebf1" id="ud770ebf1"><span data-lake-id="u31382204" id="u31382204">实例化的过程只需要调用构造函数把对象创建出来并给他分配内存空间，而初始化则是给对象的属性进行赋值。</span></p>
  <p data-lake-id="u880d1fb4" id="u880d1fb4"><span data-lake-id="u78716456" id="u78716456">​</span><br></p>
  <p data-lake-id="u3299ec23" id="u3299ec23"><span data-lake-id="u6d348b68" id="u6d348b68">而Spring之所以可以解决循环依赖就是因为对象的初始化是可以延后的，也就是说，当我创建一个Bean ServiceA的时候，会先把这个对象实例化出来，然后再初始化其中的serviceB属性。</span></p>
  <p data-lake-id="u968cc48c" id="u968cc48c"><span data-lake-id="u2e58482e" id="u2e58482e">​</span><br></p>
  <pre lang="java"><code>
@Service
public class ServiceA{

	@Autowired
	private ServiceB serviceB;

}


@Service
public class ServiceB{

	@Autowired
	private ServiceA serviceA;

}
</code></pre>
  <p data-lake-id="u395223f4" id="u395223f4"><br></p>
  <p data-lake-id="ud64fc111" id="ud64fc111"><span data-lake-id="u2ab1abee" id="u2ab1abee">而当一个对象只进行了实例化，但是还没有进行初始化时，我们称之为</span><strong><span data-lake-id="u64aa7623" id="u64aa7623">半成品对象</span></strong><span data-lake-id="ua8d7043f" id="ua8d7043f">。所以，所谓半成品对象，其实只是 bean 对象的一个空壳子，还没有进行属性注入和初始化。</span></p>
  <p data-lake-id="uabdbbb97" id="uabdbbb97"><span data-lake-id="u7bef791f" id="u7bef791f">​</span><br></p>
  <p data-lake-id="u5ce68203" id="u5ce68203"><span data-lake-id="u4c13fbfe" id="u4c13fbfe">当两个Bean在初始化过程中互相依赖的时候，如初始化A发现他依赖了B，继续去初始化B，发现他又依赖了A，那这时候怎么办呢？大致流程如下：</span></p>
  <p data-lake-id="u4dfd34b1" id="u4dfd34b1"><br></p>
  <p data-lake-id="u8a7c3504" id="u8a7c3504"><br></p>
  <p data-lake-id="uda611f62" id="uda611f62"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1696145328593-e6b49a1c-55c6-48ce-ab87-c67f88a76359.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_55%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ud1199c44" id="ud1199c44"><br></p>
  <p data-lake-id="u1ebc2633" id="u1ebc2633"><span data-lake-id="ud4c1b9b1" id="ud4c1b9b1">通过以上方式，就通过引入三级缓存，解决了循环依赖的问题，在上述流程执行完之后，ServiceA和ServiceB都被成功的完成了实例化和初始化。</span></p>
  <p data-lake-id="u4dcedd80" id="u4dcedd80"><span data-lake-id="u885c1075" id="u885c1075">​</span><br></p>
  <p data-lake-id="u930f8d23" id="u930f8d23"><span data-lake-id="u9b1d762a" id="u9b1d762a">以下是DefaultSingletonBeanRegistry#getSingleton方法，代码中，包括一级缓存、二级缓存、三级缓存的处理逻辑，该方法是获取bean的单例实例对象的核心方法：</span></p>
  <p data-lake-id="ua4ba955c" id="ua4ba955c"><span data-lake-id="u329a1bd2" id="u329a1bd2">​</span><br></p>
  <pre lang="java"><code>
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 首先从一级缓存中获取bean实例对象，如果已经存在，则直接返回
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null &amp;&amp; isSingletonCurrentlyInCreation(beanName)) {
        // 如果一级缓存中不存在bean实例对象，而且当前bean正在创建中，则从二级缓存中获取bean实例对象
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null &amp;&amp; allowEarlyReference) {
            // 如果二级缓存中也不存在bean实例对象，并且允许提前引用，则需要在锁定一级缓存之前，
            // 先锁定二级缓存，然后再进行一系列处理
            synchronized (this.singletonObjects) {
                // 进行一系列安全检查后，再次从一级缓存和二级缓存中获取bean实例对象
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null) {
                        // 如果二级缓存中也不存在bean实例对象，则从三级缓存中获取bean的ObjectFactory，并创建bean实例对象
                        ObjectFactory&lt;?&gt; singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            singletonObject = singletonFactory.getObject();
                            // 将创建好的bean实例对象存储到二级缓存中
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            // 从三级缓存中移除bean的ObjectFactory
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }
    return singletonObject;
}

</code></pre>
  <p data-lake-id="u626f17b5" id="u626f17b5"><br></p>
  <p data-lake-id="u46baed58" id="u46baed58"><br></p>
  <h1 data-lake-id="ZN3rh" id="ZN3rh"><span data-lake-id="u1153ff26" id="u1153ff26">扩展知识</span></h1>
  <p data-lake-id="u0c2b1e7c" id="u0c2b1e7c"><br></p>
 </body>
</html>